home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 142
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan).7z
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan) (Track 1).bin
/
tools
/
s44play
/
s44p101s.lzh
/
adpcm.s
next >
Wrap
Text File
|
1999-11-16
|
14KB
|
512 lines
.include global.mac
.include preconv.mac
ADPCM2PCM_BUFFER_SIZE equ 4096 ;最大256KB=262144(ループカウンタの制限)
;----------------------------------------------------------------
;ADPCMデコーダの準備
.text
.align 4,$2048
init_adpcm::
bsr make_adpcm2pcm_table
move.l #adpcm2pcm_table,preconv_adpcm_pos
clr.w preconv_adpcm_pcm
rts
.data
.even
preconv_adpcm_pcm: .ds.w 1
.align 4
preconv_adpcm_pos: .ds.l 1
;----------------------------------------------------------------
;ADPCM→PCM変換テーブルを作る
PREDICTION_STAGES equ 49 ;予測指標の数(最大74まで)
.text
.align 4,$2048
make_adpcm2pcm_table:
movem.l d0-d7/a0-a6,-(sp)
tst.b adpcm2pcm_table_constructed
bne 99f
;ADPCMデータ(0~15)毎のスケーリング済みの予測値のテーブルを作る
lea.l (base_prediction_table,pc),a0
lea.l scaled_prediction_table,a1
moveq.l #PREDICTION_STAGES-1,d3
3: lea.l (2*8,a1),a2
move.w (a0)+,d1 ;1/8×8
.if 0
;整数乗算なので誤差は蓄積しない
move.w d1,d2 ;1/8×8
add.w d2,d2 ;2/8×8
.else
;小数点以下を切り捨てる
.endif
;0,8→1/8,-1/8
.if 0
move.w d1,d0 ;1/8×8
.else
move.w d1,d0 ;1/8×8
lsr.w #3,d0
lsl.w #2,d0
move.w d0,d2
add.w d0,d0
add.w d2,d0
.endif
move.w d0,(a1)+
neg.w d0 ;-1/8×8
move.w d0,(a2)+
;1,9→3/8,-3/8
.if 0
add.w d2,d1 ;3/8×8
move.w d1,d0 ;3/8×8
.else
move.w d1,d0
lsr.w #2,d0
move.w d0,d2
lsr.w #1,d0
add.w d2,d0
lsl.w #2,d0
move.w d0,d2
add.w d0,d0
add.w d2,d0
.endif
move.w d0,(a1)+
neg.w d0 ;-3/8×8
move.w d0,(a2)+
;2,10→5/8,-5/8
.if 0
add.w d2,d1 ;5/8×8
move.w d1,d0 ;5/8×8
.else
move.w d1,d0
lsr.w #1,d0
move.w d0,d2
lsr.w #2,d0
add.w d2,d0
lsl.w #2,d0
move.w d0,d2
add.w d0,d0
add.w d2,d0
.endif
move.w d0,(a1)+
neg.w d0 ;-5/8×8
move.w d0,(a2)+
;3,11→7/8,-7/8
.if 0
add.w d2,d1 ;7/8×8
move.w d1,d0 ;7/8×8
.else
move.w d1,d0
lsr.w #1,d0
move.w d0,d2
lsr.w #1,d0
add.w d0,d2
lsr.w #1,d0
add.w d2,d0
lsl.w #2,d0
move.w d0,d2
add.w d0,d0
add.w d2,d0
.endif
move.w d0,(a1)+
neg.w d0 ;-7/8×8
move.w d0,(a2)+
;4,12→9/8,-9/8
.if 0
add.w d2,d1 ;9/8×8
move.w d1,d0 ;9/8×8
.else
move.w d1,d0
lsr.w #3,d0
add.w d1,d0
lsl.w #2,d0
move.w d0,d2
add.w d0,d0
add.w d2,d0
.endif
move.w d0,(a1)+
neg.w d0 ;-9/8×8
move.w d0,(a2)+
;5,13→11/8,-11/8
.if 0
add.w d2,d1 ;11/8×8
move.w d1,d0 ;11/8×8
.else
move.w d1,d0
lsr.w #2,d0
move.w d0,d2
lsr.w #1,d0
add.w d2,d0
add.w d1,d0
lsl.w #2,d0
move.w d0,d2
add.w d0,d0
add.w d2,d0
.endif
move.w d0,(a1)+
neg.w d0 ;-11/8×8
move.w d0,(a2)+
;6,14→13/8,-13/8
.if 0
add.w d2,d1 ;13/8×8
move.w d1,d0 ;13/8×8
.else
move.w d1,d0
lsr.w #1,d0
move.w d0,d2
lsr.w #2,d0
add.w d2,d0
add.w d1,d0
lsl.w #2,d0
move.w d0,d2
add.w d0,d0
add.w d2,d0
.endif
move.w d0,(a1)+
neg.w d0 ;-13/8×8
move.w d0,(a2)+
;7,15→15/8,-15/8
.if 0
add.w d2,d1 ;15/8×8
move.w d1,d0 ;15/8×8
.else
move.w d1,d0
lsr.w #1,d0
move.w d0,d2
lsr.w #1,d0
add.w d0,d2
lsr.w #1,d0
add.w d2,d0
add.w d1,d0
lsl.w #2,d0
move.w d0,d2
add.w d0,d0
add.w d2,d0
.endif
move.w d0,(a1)+
neg.w d0 ;-15/8×8
move.w d0,(a2)+
;
movea.l a2,a1
dbra d3,3b
;
;ADPCMデータ(0~15)毎の予測指標の遷移のテーブルを作る
lea.l (walking_clip_table,pc),a0 ;予測指標のクリッピングのテーブルの先頭+予測指標×2
lea.l prediction_walking_table,a1 ;予測指標の遷移のテーブルの先頭
moveq.l #PREDICTION_STAGES-1,d3
3: lea.l (2*8,a1),a2
;0,1,2,3,8,9,10,11→-1
move.w (-2*1,a0),d0 ;(予測指標-1)×32,クリッピング済み
move.w d0,(a1)+
move.w d0,(a2)+
move.w d0,(a1)+
move.w d0,(a2)+
move.w d0,(a1)+
move.w d0,(a2)+
move.w d0,(a1)+
move.w d0,(a2)+
;4,12→+2
move.w (+2*2,a0),d0 ;(予測指標+2)×32,クリッピング済み
move.w d0,(a1)+
move.w d0,(a2)+
;5,13→+4
move.w (+2*4,a0),d0 ;(予測指標+4)×32,クリッピング済み
move.w d0,(a1)+
move.w d0,(a2)+
;6,14→+6
move.w (+2*6,a0),d0 ;(予測指標+6)×32,クリッピング済み
move.w d0,(a1)+
move.w d0,(a2)+
;7,15→+8
move.w (+2*8,a0),d0 ;(予測指標+8)×32,クリッピング済み
move.w d0,(a1)+
move.w d0,(a2)+
;
addq.l #2,a0 ;予測指標のクリッピングのテーブルの先頭+予測指標×2
movea.l a2,a1
dbra d3,3b
;
;ADPCM→PCM変換テーブルを作る
;下位→上位
lea.l adpcm2pcm_table,a1 ;ADPCM→PCM変換テーブルの先頭
lea.l scaled_prediction_table,a4 ;スケーリング済みの予測値のテーブルの先頭
lea.l prediction_walking_table,a5 ;予測指標の遷移のテーブルの先頭
movea.l a1,a0 ;ADPCM→PCM変換テーブルの先頭
; +1番目の予測指標×2048
; +ADPCMデータ×8
movea.l a4,a2 ;スケーリング済みの予測値のテーブルの先頭
; +1番目の予測指標×32
; +下位4ビット(0~15)×2
movea.l a5,a3 ;予測指標の遷移のテーブルの先頭
; +1番目の予測指標×32
; +下位4ビット(0~15)×2
moveq.l #PREDICTION_STAGES-1,d3
3: moveq.l #0,d2 ;上位4ビット(0~15)×2
moveq.l #16-1,d1
1:
.rept 16
move.w (a2)+,(a0)+ ;1番目(下位4ビット)の予測値
move.w (a3)+,d0 ;2番目の予測指標×32
add.w d2,d0 ;2番目の予測指標×32+上位4ビット(0~15)×2
move.w (a4,d0.w),(a0)+ ;2番目(上位4ビット)の予測値
move.w (a5,d0.w),d0 ;次回の予測指標×32
ext.l d0
asl.l #6,d0 ;次回の予測指標×2048
add.l a1,d0 ;ADPCM→PCM変換テーブルの先頭+次回の予測指標×2048
move.l d0,(a0)+ ;ADPCM→PCM変換テーブルの先頭+次回の予測指標×2048
.endm
addq.w #2,d2 ;上位4ビット(0~15)×2
lea.l (-2*16,a2),a2
lea.l (-2*16,a3),a3
dbra d1,1b
lea.l (+2*16,a2),a2
lea.l (+2*16,a3),a3
dbra d3,3b
;
st.b adpcm2pcm_table_constructed
99: movem.l (sp)+,d0-d7/a0-a6
rts
BASE_PREDICTION .macro n,val
.if n<PREDICTION_STAGES
@ans = val+0.125 ;0.125加えてから切り捨てる→7捨8入
.dc.w @ans
.fail @ans>32767
.endif
.endm
;予測指標から予測値を求めるためのテーブル
; 32768/1.1^(80-n)のテーブル
.even
base_prediction_table:
.if 0
BASE_PREDICTION 0,15.9968739344382707796302152641
BASE_PREDICTION 1,17.5965613278820978575932367905
BASE_PREDICTION 2,19.3562174606703076433525604696
BASE_PREDICTION 3,21.2918392067373384076878165165
BASE_PREDICTION 4,23.4210231274110722484565981682
BASE_PREDICTION 5,25.763125440152179473302257985
BASE_PREDICTION 6,28.3394379841673974206324837835
BASE_PREDICTION 7,31.1733817825841371626957321618
BASE_PREDICTION 8,34.290719960842550878965305378
BASE_PREDICTION 9,37.7197919569268059668618359158
BASE_PREDICTION 10,41.4917711526194865635480195074
BASE_PREDICTION 11,45.6409482678814352199028214581
BASE_PREDICTION 12,50.205043094669578741893103604
BASE_PREDICTION 13,55.2255474041365366160824139644
BASE_PREDICTION 14,60.7481021445501902776906553608
BASE_PREDICTION 15,66.8229123590052093054597208969
BASE_PREDICTION 16,73.5052035949057302360056929866
BASE_PREDICTION 17,80.8557239543963032596062622852
BASE_PREDICTION 18,88.9412963498359335855668885137
BASE_PREDICTION 19,97.8354259848195269441235773651
BASE_PREDICTION 20,107.618968583301479638535935102
BASE_PREDICTION 21,118.380865441631627602389528612
BASE_PREDICTION 22,130.218951985794790362628481473
BASE_PREDICTION 23,143.24084718437426939889132962
BASE_PREDICTION 24,157.564931902811696338780462582
BASE_PREDICTION 25,173.321425093092865972658508841
BASE_PREDICTION 26,190.653567602402152569924359725
BASE_PREDICTION 27,209.718924362642367826916795697
BASE_PREDICTION 28,230.690816798906604609608475267
BASE_PREDICTION 29,253.759898478797265070569322793
BASE_PREDICTION 30,279.135888326676991577626255073
BASE_PREDICTION 31,307.04947715934469073538888058
BASE_PREDICTION 32,337.754424875279159808927768638
BASE_PREDICTION 33,371.529867362807075789820545502
BASE_PREDICTION 34,408.682854099087783368802600052
BASE_PREDICTION 35,449.551139508996561705682860057
BASE_PREDICTION 36,494.506253459896217876251146063
BASE_PREDICTION 37,543.956878805885839663876260669
BASE_PREDICTION 38,598.352566686474423630263886736
BASE_PREDICTION 39,658.18782335512186599329027541
BASE_PREDICTION 40,724.006605690634052592619302951
BASE_PREDICTION 41,796.407266259697457851881233246
BASE_PREDICTION 42,876.04799288566720363706935657
BASE_PREDICTION 43,963.652792174233924000776292227
BASE_PREDICTION 44,1060.01807139165731640085392145
BASE_PREDICTION 45,1166.0198785308230480409393136
BASE_PREDICTION 46,1282.62186638390535284503324495
BASE_PREDICTION 47,1410.88405302229588812953656945
BASE_PREDICTION 48,1551.9724583245254769424902264
BASE_PREDICTION 49,1707.16970415697802463673924903
BASE_PREDICTION 50,1877.88667457267582710041317394
BASE_PREDICTION 51,2065.67534202994340981045449133
;↑15倍が32767を越えない範囲
BASE_PREDICTION 52,2272.24287623293775079149994047
BASE_PREDICTION 53,2499.46716385623152587064993451
BASE_PREDICTION 54,2749.41388024185467845771492796
BASE_PREDICTION 55,3024.35526826604014630348642076
BASE_PREDICTION 56,3326.79079509264416093383506283
BASE_PREDICTION 57,3659.46987460190857702721856912
BASE_PREDICTION 58,4025.41686206209943472994042603
BASE_PREDICTION 59,4427.95854826830937820293446863
BASE_PREDICTION 60,4870.7544030951403160232279155
BASE_PREDICTION 61,5357.82984340465434762555070705
BASE_PREDICTION 62,5893.61282774511978238810577775
BASE_PREDICTION 63,6482.97411051963176062691635553
BASE_PREDICTION 64,7131.27152157159493668960799108
BASE_PREDICTION 65,7844.39867372875443035856879019
BASE_PREDICTION 66,8628.83854110162987339442566921
BASE_PREDICTION 67,9491.72239521179286073386823613
BASE_PREDICTION 68,10440.8946347329721468072550597
BASE_PREDICTION 69,11484.9840982062693614879805657
BASE_PREDICTION 70,12633.4825080268962976367786223
BASE_PREDICTION 71,13896.8307588295859274004564845
BASE_PREDICTION 72,15286.513834712544520140502133
BASE_PREDICTION 73,16815.1652181837989721545523463
;↑15/8倍が32767を越えない範囲
BASE_PREDICTION 74,18496.6817400021788693700075809
BASE_PREDICTION 75,20346.349914002396756307008339
BASE_PREDICTION 76,22380.9849054026364319377091729
BASE_PREDICTION 77,24619.0833959429000751314800902
BASE_PREDICTION 78,27080.9917355371900826446280992
BASE_PREDICTION 79,29789.0909090909090909090909091
;↑32767を越えない範囲
.else
;PCM8.Xのテーブル
.fail PREDICTION_STAGES<>49
.dc.w 16, 17, 19, 21, 23, 25, 28
.dc.w 31, 34, 37, 41, 45, 50, 55
.dc.w 60, 66, 73, 80, 88, 97, 107
.dc.w 118, 130, 143, 157, 173, 190, 209
.dc.w 230, 253, 279, 307, 337, 371, 408
.dc.w 449, 494, 544, 598, 658, 724, 796
.dc.w 876, 963,1060,1166,1282,1411,1552
.endif
;予測指標のクリッピングのテーブル
; 予測指標が範囲内に収まるようにクリッピングする
; マイナス側は最小値-1まで,プラス側は最大値+8まで必要.
; テーブルのオフセットに使うのであらかじめ32倍しておく.
.even
.dc.w 0*32
walking_clip_table:
n = 0
.rept PREDICTION_STAGES
.dc.w n*32
n = n+1
.endm
.rept 8
.dc.w (PREDICTION_STAGES-1)*32
.endm
.data
adpcm2pcm_table_constructed:
.dc.b 0 ;-1=ADPCM→PCM変換テーブル生成済み
.bss
;ADPCMデータ(0~15)毎のスケーリング済みの予測値のテーブル
; 予測値をADPCMデータ(0~15)毎にスケーリングした結果
.even
scaled_prediction_table:
.ds.w 16*PREDICTION_STAGES
;ADPCMデータ(0~15)毎の予測指標の遷移のテーブル
; 予測指標はADPCMデータ(0~15)毎に遷移先が異なる.
; ADPCMデータ(0~15)毎の予測指標の遷移先を32倍したテーブル.
.even
prediction_walking_table:
.ds.w 16*PREDICTION_STAGES
;ADPCM→PCM変換テーブル
; 予測指標とADPCMデータ(4ビット×2データ=1バイト)から,
; 1番目の予測値.w
; 2番目の予測値.w
; ADPCM→PCM変換テーブルの先頭+次回の予測指標×2048.l
; の8バイトを求めるためのテーブル.
.align 8
adpcm2pcm_table:
.ds.b 8*256*PREDICTION_STAGES
;----------------------------------------------------------------
;----------------------------------------------------------------
;ADPCMデータの前処理(ADPCMデータをOPMのTLの並びに変換する)
;<a0.l:出力バッファの先頭
;<a1.l:入力データの先頭
;<a2.l:入力データの末尾+1
;>a0.l:出力データの末尾+1
;>a1.l:出力データの先頭
;?d1-d7/a2-a6
.text
START_PRECONV_BUFFER .macro side
bsr adpcm2pcm_block
movea.l preconv_dst_top_ptr,Adst
.endm
LOOP_PRECONV_BUFFER .macro side
bsr adpcm2pcm_block
cmpa.l Asrc,Alim
beq @f
jmp (Ajmp)
@@:
.endm
GET_DATA_0 .macro src,dat,tmp
move.w (src)+,dat
.endm
.irp %q,LQ,HQ,SQ
.align 4,$2048
preconv_adpcm_%q::
move.l a0,preconv_dst_top_ptr
move.l a1,preconv_src_cur_ptr
move.l a2,preconv_src_lim_ptr
PRECONV_MONO_%q
movea.l preconv_dst_top_ptr,a1
rts
.endm
;----------------------------------------------------------------
.text
.align 4,$2048
adpcm2pcm_block:
movem.l d0-d2,-(sp)
lea.l adpcm2pcm_buffer,Alim
movea.l preconv_src_cur_ptr,Asrc
move.l preconv_src_lim_ptr,d2
sub.l Asrc,d2
beq 9f
cmp.l #ADPCM2PCM_BUFFER_SIZE/4,d2
bls @f
move.w #ADPCM2PCM_BUFFER_SIZE/4,d2
@@:
movea.l preconv_adpcm_pos,Atbl
;<Atbl.l:ADPCM→PCM変換テーブルの先頭+予測指標(0~48)*2048
move.w preconv_adpcm_pcm,d0
;<d0.w:PCMデータ
subq.w #1,d2
lsr.w #1,d2
bcc 3f
2: moveq.l #0,d1
move.b (Asrc)+,d1
lsl.w #3,d1
adda.l d1,Atbl
add.w (Atbl)+,d0
move.w d0,(Alim)+
add.w (Atbl)+,d0
move.w d0,(Alim)+
movea.l (Atbl),Atbl
3: moveq.l #0,d1
move.b (Asrc)+,d1
lsl.w #3,d1
adda.l d1,Atbl
add.w (Atbl)+,d0
move.w d0,(Alim)+
add.w (Atbl)+,d0
move.w d0,(Alim)+
movea.l (Atbl),Atbl
dbra d2,2b
move.w d0,preconv_adpcm_pcm
move.l Atbl,preconv_adpcm_pos
move.l Asrc,preconv_src_cur_ptr
9: lea.l pcm2tl_table+32768,Atbl
lea.l adpcm2pcm_buffer,Asrc
movem.l (sp)+,d0-d2
rts
.bss
.align 4
adpcm2pcm_buffer: .ds.b ADPCM2PCM_BUFFER_SIZE